package com.jrapider.designer.listener;


import com.baomidou.mybatisplus.core.toolkit.sql.SqlHelper;
import com.jrapider.designer.service.SysEntityFieldService;
import com.jrapider.designer.service.SysEntityService;
import com.jrapider.CommonConstants;
import com.jrapider.om.SysEntityField;
import com.jrapider.utils.TypeMapper;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.sql.*;


/**
 * Created by Administrator on 2018/7/31.
 * 爬虫规则启动器
 */
@Component
public class DataInit implements ApplicationListener<ApplicationReadyEvent> {
    private static final Logger LOG = LoggerFactory.getLogger(DataInit.class);

    @Value("${designer.schema:}")
    private String schema;

    @Autowired
    private SysEntityService sysEntityService;
    @Autowired
    private SysEntityFieldService sysEntityFieldService;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        LOG.info("捕获Spring事件-ApplicationReadyEvent" + event.getClass().getName());
        SqlSession sqlSession = null;
        ResultSet rs = null;
        ResultSet tableRs = null;
        Connection conn = null;
        Statement statement = null;
        String[] schemas = schema.split(",");
        try {
            String tableName;
            sqlSession = SqlHelper.FACTORY.openSession();
            conn = sqlSession.getConnection();
            DatabaseMetaData db = conn.getMetaData();
            for (String targetSchema : schemas) {
                //从元数据中获取到所有的表名
                rs = db.getTables(targetSchema, null, null, new String[]{"TABLE"});
                while (rs.next()) {
                    tableName = rs.getString(3);
                    LOG.info("{}-开始提取数据...", tableName);
                    Long entityId = sysEntityService.saveAndGetId(tableName);
                    statement = conn.createStatement();
                    tableRs = statement.executeQuery("show full columns from " + tableName);
                    while (tableRs.next()) {
                        String column = tableRs.getString("Field");
                        String dbType = tableRs.getString("Type");
                        String primaryKey = tableRs.getString("Key");
                        String required = tableRs.getString("Null");
                        String comment = tableRs.getString("Comment");
                        LOG.info("字段名称：{}\t字段类型：{}\t字段注释：{}\t主键：{}", column, dbType, comment, primaryKey);
                        SysEntityField sysEntityField = new SysEntityField();
                        sysEntityField.setColumnEx(column);
                        sysEntityField.setDbType(dbType);
                        sysEntityField.setCommentEx(comment);
                        sysEntityField.setEntityId(entityId);
                        //非空属性,YES=允许空
                        if (required.equals("YES")) {
                            sysEntityField.setRequired(CommonConstants.DICT_TF_FALSE);
                        } else {
                            sysEntityField.setRequired(CommonConstants.DICT_TF_TRUE);
                        }
                        //字段类型
                        sysEntityField.setFieldType(TypeMapper.getJavaType(sysEntityField.getDbType()));
                        //主键
                        if (!StringUtils.isEmpty(primaryKey) && "PRI".equals(primaryKey)) {
                            sysEntityField.setPrimaryEx(CommonConstants.DICT_TF_TRUE);
                        } else {
                            sysEntityField.setPrimaryEx(CommonConstants.DICT_TF_FALSE);
                        }
                        sysEntityFieldService.saveAndGetId(sysEntityField);
                    }
                    tableRs.close();
                    statement.close();
                }
                rs.close();
            }
        } catch (SQLException e) {
            LOG.error(e.getMessage(), e);
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    LOG.error(e.getMessage(), e);
                }
            }
            if (tableRs != null) {
                try {
                    tableRs.close();
                } catch (SQLException e) {
                    LOG.error(e.getMessage(), e);
                }
            }
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    LOG.error(e.getMessage(), e);
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    LOG.error(e.getMessage(), e);
                }
            }
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }

}
